#include <stdio.h>
#include <stdint.h>

#define true  ((unsigned char)1)
#define false ((unsigned char)0)
#define SIZEOF_ARRAY(a) (sizeof(a) / sizeof(a[0]))
#define NMAX 100000
#define PIPE_DATA_TYPE long long

static const long long divisors[] = { 2, 3, 5, 7, 11, 13 };

/* {{{ truba */
#ifndef PIPE_DATA_TYPE
#define PIPE_DATA_TYPE int
#endif

#ifndef NMAX
#define NMAX 500000
#endif
struct Pipe {
	PIPE_DATA_TYPE data[NMAX];
	int head;
	int size;
};

extern void
Clear(struct Pipe * p)
{
	p->size = 0;
	p->head = 0;
}



extern int
Push(struct Pipe * p, PIPE_DATA_TYPE key)
{
	if (p->size / NMAX >= 1)
		return -1; /* queue is full */
	p->data[(p->head + p->size) % NMAX] = key;
	++p->size;
	return 0;
}



extern PIPE_DATA_TYPE
Pop(struct Pipe * p)
{
	PIPE_DATA_TYPE ret = p->data[p->head % NMAX];
	if (!p->size)
		return ret; /* a.k.a. UB */
	--p->size;
	if (++p->head == NMAX)
		p->head = 0;
	return ret;
}



extern PIPE_DATA_TYPE
Head(const struct Pipe * p)
{
	return p->data[p->head];
}



extern PIPE_DATA_TYPE
Tail(const struct Pipe * p)
{
	return p->data[(p->head + p->size - 1) % NMAX];
}



extern unsigned char
IsEmpty(const struct Pipe * p)
{
	return p->size ? 0 : 1;
}
/* }}} */


/* {{{ unused
static void
print_heads(struct Pipe * p, int n)
{
	register int i = 0;
	while (i < n) {
		(void) fprintf(stderr, "%2d's head: %3d\n", i, Head(p+i));
		++i;
	}
}
 }}} */


static int
print_and_push(PIPE_DATA_TYPE what, struct Pipe * p, int n)
{
	int ret = 0;
	register short i;

	(void) printf("%lld ", what);
	for (i = 0 ; i < n ; ++i)
		ret |= Push(p + i, what * divisors[i]);
	return ret ? 0 : 1; /* 0 if everything is ok
			       1 if there were problems */
}


int
main(void)
{
	struct Pipe p[SIZEOF_ARRAY(divisors)];
	int n;
	register int i = 0, j = 0;
	PIPE_DATA_TYPE min;
	int min_idx = 0;

	(void) freopen("numbers.in", "r", stdin);
	(void) freopen("numbers.out","w",stdout);

	(void) fprintf(stderr, "\t This is an unauthorized copy\n");

	(void) scanf("%d", &n);

	/*
	 * It was hard to write, it should be hard to read. (c)
	 */
	for (i = 0 ; i < SIZEOF_ARRAY(p) ; ++i)
		Clear(&p[i]);
	i = 0;

	print_and_push(1, p, SIZEOF_ARRAY(p));
	++i;

	min     = Head(p); /* 'p' will degrade into '&p[0]' */
	min_idx = 0;		/* see above ^^^ */

	while (i < n) {
		//fprintf(stderr, "\nBEFORE:\n");
		//print_heads(p, SIZEOF_ARRAY(p));

		min = Head(&p[min_idx]);
		for (j = 0 ; j < SIZEOF_ARRAY(p) ; ++j) {
			if (min > Head(&p[j])) {
				min     = Head(&p[j]);
				min_idx = j;
			}
		}

		print_and_push(Pop(&p[min_idx]), p, SIZEOF_ARRAY(p));

		//fprintf(stderr, "\nAFTER 1:\n");
		//print_heads(p, SIZEOF_ARRAY(p));

		for (j = 0 ; j < SIZEOF_ARRAY(p) ; ++j) {
			if (min == Head(&p[j])) {
				//(void) fprintf(stderr, "removing %d from %d (div. %d) queue\n", Pop(&p[j]), j, divisors[j]);
				(void) Pop(&p[j]);
			}
		}

		//fprintf(stderr, "\nAFTER 2:\n");
		//print_heads(p, SIZEOF_ARRAY(p));

		++i;
	}

	putc('\n', stdout);
	return 0;
}
// vim:foldmethod=marker:
